<script lang="ts">
  import * as echarts from 'echarts'
  import axios from 'axios'
  import type { DailyModel } from '@/model/DailyModel'
  import type { EChartsType } from 'echarts/types/dist/echarts'
  import { useRoute } from 'vue-router'
  import { calDea, calDif } from '@/util/CalMacdUtil'
  import { calKdj } from '@/util/CalKdjUtil'
  import type { HkHoldModel } from '@/model/HkHoldModel'
  import type { HoldNumberModel } from '@/model/HoldNumberModel'
  import type { MarginDetailModel } from '@/model/MarginDetailModel'

  const upColor = '#ff0000'
  const downColor = '#00ff00'
  const firstLineColor = '#c0c0c0'
  const secondLineColor = '#ffff00'
  const threeLineColor = '#ff00ff'

  export default {

    // 1.K线图；2.成交量；3.macd；4.kdj；5.北向资金；6.股东人数；7.融资融券；
    mounted() {
      console.log('mounted')
      const mainDom = document.getElementById('main')
      if (mainDom == null) {
        return
      }
      const route = useRoute()
      const ts_code = route.query.ts_code
      const mainChart: EChartsType = echarts.init(mainDom)
      axios.get('src/assets/config.json')
        .then(response => Promise.all([axios.get(`${response.data.url}loadDaily?ts_code=${ts_code}`, { method: 'GET' }),
          axios.get(`${response.data.url}loadHkHold?ts_code=${ts_code}`, { method: 'GET' }),
          axios.get(`${response.data.url}loadHoldNumber?ts_code=${ts_code}`, { method: 'GET' }),
          axios.get(`${response.data.url}loadMarginDetail?ts_code=${ts_code}`, { method: 'GET' })]))
        .then(([dailyResponse, hkHoldResponse, holdNumberResponse, marginDetailResponse]) => {
          const dailyList: Array<DailyModel> = dailyResponse.data
          const hkHoldList: Array<HkHoldModel> = hkHoldResponse.data
          const holdNumberList: Array<HoldNumberModel> = holdNumberResponse.data
          const marginDetailList: Array<MarginDetailModel> = marginDetailResponse.data
          console.log(holdNumberResponse)
          this.initMainChart(dailyList, hkHoldList, holdNumberList, marginDetailList, mainChart)
        })
        .catch(err => console.log(err))
    },
    methods: {
      calVolumes: function(dailyList: Array<DailyModel>) {
        return dailyList.map((daily, index) => [index, daily.amount, daily.open < daily.close ? -1 : 1])
      },
      calValues: function(dailyList: Array<DailyModel>) {
        return dailyList.map(daily => [daily.open, daily.close, daily.low, daily.high])
      },
      calCategoryData: function(dailyList: Array<DailyModel>) {
        return dailyList.map(daily => daily.trade_date)
      },
      calMa: function(dayCount: number, dailyList: Array<DailyModel>) {
        const result = []
        for (let i = 0, len = dailyList.length; i < len; i++) {
          if (i < dayCount) {
            result.push('-')
            continue
          }
          let sum = 0
          for (let j = 0; j < dayCount; j++) {
            sum += dailyList[i - j].close
          }
          result.push(+(sum / dayCount).toFixed(3))
        }
        return result
      },
      initMainChart: function(dailyList: Array<DailyModel>, hkHoldList: Array<HkHoldModel>, holdNumberList: Array<HoldNumberModel>,
                              marginDetailList: Array<MarginDetailModel>, chartsType: EChartsType) {
        const categoryData = this.calCategoryData(dailyList)
        const diffList = calDif(dailyList)
        const deaList = calDea(diffList)
        const macdList: Array<any> = []
        dailyList.forEach((daily, index) => {
          const macd = 2 * (diffList[index] - deaList[index])
          macdList.push({
            value: macd,
            itemStyle: { color: macd >= 0 ? upColor : downColor }
          })
        })
        const kdjList = calKdj(dailyList)
        const transKList = kdjList[0].map(value => value - 50)
        const transDList = kdjList[1].map(value => value - 50)
        const transJList = kdjList[2].map(value => value - 50)
        const kdjDiffList: Array<any> = []
        dailyList.forEach((daily, index) => {
          const kdjDiff = transJList[index] - transKList[index]
          kdjDiffList.push({
            value: kdjDiff,
            itemStyle: { color: kdjDiff >= 0 ? upColor : downColor }
          })
        })
        const adjustHkHolderList: HkHoldModel[] = []
        dailyList.forEach((daily, index) => {
          let hkHolder = hkHoldList.find(hold => hold.trade_date === daily.trade_date)
          if (hkHolder === undefined) {
            hkHolder = {
              ts_code: daily.ts_code, trade_date: daily.trade_date,
              name: '', ratio: 0, vol: 0, exchange: ''
            }
            if (index !== 0) {
              const preHkHold = adjustHkHolderList[index - 1]
              hkHolder.name = preHkHold.name
              hkHolder.ratio = preHkHold.ratio
              hkHolder.vol = preHkHold.vol
              hkHolder.exchange = preHkHold.exchange
            }
          }
          adjustHkHolderList.push(hkHolder)
        })
        hkHoldList = adjustHkHolderList
        dailyList.forEach((daily, index) => {
          const emptyHoldNumber = {
            id: daily.ts_code,
            ts_code: daily.ts_code,
            ann_date: daily.trade_date,
            end_date: daily.trade_date,
            holder_num: 0
          }
          if (index >= holdNumberList.length) {
            holdNumberList.splice(index, 0, emptyHoldNumber)
            return
          }
          const holdNumber = holdNumberList[index]
          if (holdNumber.ann_date !== daily.trade_date) {
            if (index !== 0) {
              const preHkHold = holdNumberList[index - 1]
              emptyHoldNumber.holder_num = preHkHold.holder_num
            }
            holdNumberList.splice(index, 0, emptyHoldNumber)
          }
        })
        const adjustMarginDetailList: MarginDetailModel[] = []
        dailyList.forEach((daily, index) => {
          let marginDetail = marginDetailList.find(marginDetail => marginDetail.trade_date === daily.trade_date)
          if (marginDetail === undefined) {
            marginDetail = {
              ts_code: daily.ts_code, trade_date: daily.trade_date, rzye: 0, rqye: 0
            }
            if (index !== 0) {
              const preMarginDetail = adjustMarginDetailList[index - 1]
              marginDetail.rzye = preMarginDetail.rzye
              marginDetail.rqye = preMarginDetail.rqye
            }
          }
          adjustMarginDetailList.push(marginDetail)
        })
        marginDetailList = adjustMarginDetailList
        console.log(dailyList, hkHoldList, marginDetailList)
        const option = {
          animation: false,
          legend: {
            top: 10,
            left: 'center',
            data: [dailyList[0].ts_code, 'MA5', 'MA10', 'MA20', 'MA30']
          },
          tooltip: {
            trigger: 'axis',
            axisPointer: {
              type: 'cross'
            },
            borderWidth: 1,
            borderColor: '#ccc',
            padding: 10,
            textStyle: {
              color: '#000'
            },
            position: function(pos: any, params: any, el: any, elRect: any, size: any) {
              const obj: any = {
                top: 10
              }
              obj[['left', 'right'][+(pos[0] < size.viewSize[0] / 2)]] = 30
              return obj
            }
          },
          axisPointer: {
            link: [{
              xAxisIndex: 'all'
            }],
            label: {
              backgroundColor: '#777'
            }
          },
          toolbox: {
            feature: {
              dataZoom: {
                yAxisIndex: false
              },
              brush: {
                type: ['lineX', 'clear']
              }
            }
          },
          brush: {
            xAxisIndex: 'all',
            brushLink: 'all',
            outOfBrush: {
              colorAlpha: 0.1
            }
          },
          visualMap: {
            show: false,
            seriesIndex: 5,
            dimension: 2,
            pieces: [{
              value: 1,
              color: downColor
            }, {
              value: -1,
              color: upColor
            }]
          },
          grid: [{
            left: '2%',
            right: '2%',
            height: '350px'
          }, {
            left: '2%',
            right: '2%',
            top: '350px',
            height: '120px'
          }, {
            left: '2%',
            right: '2%',
            top: '480px',
            height: '70px'
          }, {
            left: '2%',
            right: '2%',
            top: '550px',
            height: '70px'
          }, {
            left: '2%',
            right: '2%',
            top: '620px',
            height: '70px'
          }, {
            left: '2%',
            right: '2%',
            top: '700px',
            height: '70px'
          }, {
            left: '2%',
            right: '2%',
            top: '780px',
            height: '70px'
          }],
          xAxis: [{
            type: 'category',
            data: categoryData,
            boundaryGap: false,
            axisLine: { onZero: false },
            splitLine: { show: false },
            min: 'dataMin',
            max: 'dataMax',
            axisPointer: {
              z: 100
            }
          }, {
            type: 'category',
            gridIndex: 1,
            data: categoryData,
            boundaryGap: false,
            axisLine: { onZero: false },
            axisTick: { show: false },
            splitLine: { show: false },
            axisLabel: { show: false },
            min: 'dataMin',
            max: 'dataMax'
          }, {
            type: 'category',
            gridIndex: 2,
            data: categoryData,
            boundaryGap: false,
            axisLine: { onZero: false },
            axisTick: { show: false },
            splitLine: { show: false },
            axisLabel: { show: false },
            min: 'dataMin',
            max: 'dataMax'
          }, {
            type: 'category',
            gridIndex: 3,
            data: categoryData,
            boundaryGap: false,
            axisLine: { onZero: false },
            axisTick: { show: false },
            splitLine: { show: false },
            axisLabel: { show: false },
            min: 'dataMin',
            max: 'dataMax'
          }, {
            type: 'category',
            gridIndex: 4,
            data: categoryData,
            boundaryGap: false,
            axisLine: { onZero: false },
            axisTick: { show: false },
            splitLine: { show: false },
            axisLabel: { show: false },
            min: 'dataMin',
            max: 'dataMax'
          }, {
            type: 'category',
            gridIndex: 5,
            data: categoryData,
            boundaryGap: false,
            axisLine: { onZero: false },
            axisTick: { show: false },
            splitLine: { show: false },
            axisLabel: { show: false },
            min: 'dataMin',
            max: 'dataMax'
          }, {
            type: 'category',
            gridIndex: 6,
            data: categoryData,
            boundaryGap: false,
            axisLine: { onZero: false },
            axisTick: { show: false },
            splitLine: { show: false },
            axisLabel: { show: false },
            min: 'dataMin',
            max: 'dataMax'
          }],
          yAxis: [{
            scale: true,
            splitArea: {
              show: true
            }
          }, {
            scale: true,
            gridIndex: 1,
            splitNumber: 2,
            axisLabel: { show: false },
            axisLine: { show: false },
            axisTick: { show: false },
            splitLine: { show: false }
          }, {
            scale: true,
            gridIndex: 2,
            splitNumber: 2,
            axisLabel: { show: false },
            axisLine: { show: false },
            axisTick: { show: false },
            splitLine: { show: false }
          }, {
            scale: true,
            gridIndex: 3,
            splitNumber: 2,
            axisLabel: { show: false },
            axisLine: { show: false },
            axisTick: { show: false },
            splitLine: { show: false }
          }, {
            scale: true,
            gridIndex: 4,
            splitNumber: 2,
            axisLabel: { show: false },
            axisLine: { show: false },
            axisTick: { show: false },
            splitLine: { show: false }
          }, {
            scale: true,
            gridIndex: 5,
            splitNumber: 2,
            axisLabel: { show: false },
            axisLine: { show: false },
            axisTick: { show: false },
            splitLine: { show: false }
          }, {
            scale: true,
            gridIndex: 6,
            splitNumber: 2,
            axisLabel: { show: false },
            axisLine: { show: false },
            axisTick: { show: false },
            splitLine: { show: false }
          }],
          dataZoom: [{
            type: 'inside',
            xAxisIndex: [0, 1, 2, 3, 4, 5, 6],
            start: 85,
            end: 100
          }],
          series: [{
            name: dailyList[0].ts_code,
            type: 'candlestick',
            data: this.calValues(dailyList),
            tooltip: {
              formatter: function(param: any) {
                param = param[0]
                return [
                  '时间: ' + param.name + '<hr size="1" style="margin: 3px 0">',
                  '开盘价: ' + param.data[0] + '<br/>',
                  '收盘价: ' + param.data[1] + '<br/>',
                  '最低价: ' + param.data[2] + '<br/>',
                  '最高价: ' + param.data[3] + '<br/>'
                ].join('')
              }
            }
          }, {
            name: 'MA5',
            type: 'line',
            data: this.calMa(5, dailyList),
            smooth: true,
            showSymbol: false,
            lineStyle: {
              opacity: 0.5
            }
          }, {
            name: 'MA10',
            type: 'line',
            data: this.calMa(10, dailyList),
            smooth: true,
            showSymbol: false,
            lineStyle: {
              opacity: 0.5
            }
          }, {
            name: 'MA20',
            type: 'line',
            data: this.calMa(20, dailyList),
            smooth: true,
            showSymbol: false,
            lineStyle: {
              opacity: 0.5
            }
          }, {
            name: 'MA30',
            type: 'line',
            data: this.calMa(30, dailyList),
            smooth: true,
            showSymbol: false,
            lineStyle: {
              opacity: 0.5
            }
          }, {
            name: 'Volume',
            type: 'bar',
            xAxisIndex: 1,
            yAxisIndex: 1,
            data: this.calVolumes(dailyList)
          }, {
            name: 'macd',
            type: 'bar',
            barWidth: 1,
            smooth: true,
            showSymbol: false,
            xAxisIndex: 2,
            yAxisIndex: 2,
            data: macdList
          }, {
            name: 'diff',
            type: 'line',
            lineStyle: {
              color: firstLineColor,
              width: 1
            },
            smooth: true,
            showSymbol: false,
            xAxisIndex: 2,
            yAxisIndex: 2,
            data: diffList
          }, {
            name: 'dea',
            type: 'line',
            lineStyle: {
              color: secondLineColor,
              width: 1
            },
            smooth: true,
            showSymbol: false,
            xAxisIndex: 2,
            yAxisIndex: 2,
            data: deaList
          }, {
            name: 'k',
            type: 'line',
            lineStyle: {
              color: firstLineColor,
              width: 1
            },
            smooth: true,
            showSymbol: false,
            xAxisIndex: 3,
            yAxisIndex: 3,
            data: transKList
          }, {
            name: 'd',
            type: 'line',
            lineStyle: {
              color: secondLineColor,
              width: 1
            },
            smooth: true,
            showSymbol: false,
            xAxisIndex: 3,
            yAxisIndex: 3,
            data: transDList
          }, {
            name: 'j',
            type: 'line',
            lineStyle: {
              color: threeLineColor,
              width: 1
            },
            smooth: true,
            showSymbol: false,
            xAxisIndex: 3,
            yAxisIndex: 3,
            data: transJList
          }, {
            name: 'kdjDiff',
            type: 'bar',
            barWidth: 1,
            smooth: true,
            showSymbol: false,
            xAxisIndex: 3,
            yAxisIndex: 3,
            data: kdjDiffList
          }, {
            name: 'khHold',
            type: 'line',
            lineStyle: {
              color: threeLineColor,
              width: 1
            },
            smooth: true,
            showSymbol: false,
            xAxisIndex: 4,
            yAxisIndex: 4,
            data: hkHoldList.map(hold => hold.ratio)
          }, {
            name: 'rqye',
            type: 'line',
            lineStyle: {
              color: threeLineColor,
              width: 1
            },
            smooth: true,
            showSymbol: false,
            xAxisIndex: 5,
            yAxisIndex: 5,
            data: marginDetailList.map(marginDetail => marginDetail.rqye)
          }, {
            name: 'rzye',
            type: 'line',
            lineStyle: {
              color: threeLineColor,
              width: 1
            },
            smooth: true,
            showSymbol: false,
            xAxisIndex: 6,
            yAxisIndex: 6,
            data: marginDetailList.map(marginDetail => marginDetail.rzye)
          }]
        }
        chartsType.setOption(option)
      }
    }
  }
</script>

<template class="container">
    <button class="left">左边</button>
    <div id="main" class="mainStyle"></div>
    <button class="right">右边</button>
</template>

<style>
    .container {
        position: relative;
    }

    .mainStyle {
        margin: 0 0 0 -90px;
        padding: 0;
        height: 1000px;
        width: 100%;
        min-width: 1400px;
    }

    .left {
        position: absolute;
        top: 40%;
        left: -8%;
        height: 20%;
    }

    .right {
        position: absolute;
        top: 40%;
        right: -8%;
        height: 20%;
    }

    @media (min-width: 1024px) {
        .about {
            min-height: 100vh;
            display: flex;
            align-items: center;
        }
    }
</style>
